package com.yuelao.yuelao_backend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuelao.yuelao_backend.common.BizException;
import com.yuelao.yuelao_backend.common.ErrorCode;
import com.yuelao.yuelao_backend.entity.VerificationCode;
import com.yuelao.yuelao_backend.mapper.VerificationCodeMapper;
import com.yuelao.yuelao_backend.service.VerificationCodeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Random;

/**
 * 验证码Service实现类
 */
@Service
@Slf4j
public class VerificationCodeServiceImpl extends ServiceImpl<VerificationCodeMapper, VerificationCode> implements VerificationCodeService {

    private static final int CODE_LENGTH = 6;
    private static final int EXPIRE_MINUTES = 5; // 验证码有效期5分钟
    private static final int RESEND_INTERVAL_SECONDS = 60; // 重发间隔60秒

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean sendCode(String phone, String type) {
        // 1. 检查最近是否发送过验证码（防止频繁发送）
        LocalDateTime oneMinuteAgo = LocalDateTime.now().minusSeconds(RESEND_INTERVAL_SECONDS);
        LambdaQueryWrapper<VerificationCode> recentWrapper = new LambdaQueryWrapper<>();
        recentWrapper.eq(VerificationCode::getPhone, phone)
                    .eq(VerificationCode::getType, type)
                    .gt(VerificationCode::getCreatedAt, oneMinuteAgo)
                    .orderByDesc(VerificationCode::getCreatedAt)
                    .last("LIMIT 1");
        
        VerificationCode recent = getOne(recentWrapper);
        if (recent != null) {
            throw new BizException(ErrorCode.OPERATION_ERROR, "验证码发送过于频繁，请稍后再试");
        }

        // 2. 生成验证码
        String code = generateCode();

        // 3. 保存到数据库
        VerificationCode verificationCode = new VerificationCode();
        verificationCode.setPhone(phone);
        verificationCode.setCode(code);
        verificationCode.setType(type);
        verificationCode.setExpireAt(LocalDateTime.now().plusMinutes(EXPIRE_MINUTES));
        verificationCode.setUsed(false);
        verificationCode.setCreatedAt(LocalDateTime.now());

        boolean saved = save(verificationCode);

        if (saved) {
            // 4. 发送短信（实际项目中需要调用短信服务商API）
            log.info("发送验证码到手机号: {}, 验证码: {}, 类型: {}", phone, code, type);
            // TODO: 集成短信服务商（阿里云、腾讯云等）
            // smsService.send(phone, code);
        }

        return saved;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean verifyCode(String phone, String code, String type) {
        // 1. 查询最新的未使用的验证码
        LambdaQueryWrapper<VerificationCode> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(VerificationCode::getPhone, phone)
               .eq(VerificationCode::getCode, code)
               .eq(VerificationCode::getType, type)
               .eq(VerificationCode::getUsed, false)
               .orderByDesc(VerificationCode::getCreatedAt)
               .last("LIMIT 1");
        
        VerificationCode verificationCode = getOne(wrapper);

        // 2. 验证码不存在
        if (verificationCode == null) {
            return false;
        }

        // 3. 检查是否过期
        if (LocalDateTime.now().isAfter(verificationCode.getExpireAt())) {
            return false;
        }

        // 4. 标记为已使用
        verificationCode.setUsed(true);
        updateById(verificationCode);

        return true;
    }

    @Override
    public String generateCode() {
        Random random = new Random();
        StringBuilder code = new StringBuilder();
        
        for (int i = 0; i < CODE_LENGTH; i++) {
            code.append(random.nextInt(10));
        }
        
        return code.toString();
    }
}

